/*
Copyright 2009 David Revell

This file is part of SwiFTP.

SwiFTP is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

SwiFTP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with SwiFTP.  If not, see <http://www.gnu.org/licenses/>.
*/
package lfr.ustc.ftp;

/**
 */
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketManager extends Thread {
	public Socket cmdSocket;
	public ServerSocket serverSocket = null;
	public String userName;
	public String pwd;
	public String usingDrirectory;
	public boolean isLogin = false;
	public File workingDir = CommonSettings.getChrootDir();
	public Socket dataSocket = null;
	public DataSocket dataSocketFactory;
	OutputStream dataOutputStream = null;
	public String encoding = "UTF-8";
	int authFails = 0;
	public static int MAX_AUTH_FAILS = 3;
	public boolean binaryMode = false;
	public String transmitType = "BINARY"; // ��ݴ�������
											// binary����ASCII����,����binaryΪĬ������
	protected File renameFrom = null;

	public void closeDataSocket() {
		if (dataOutputStream != null) {
			try {
				dataOutputStream.close();
			} catch (IOException e) {
			}
			dataOutputStream = null;
		}
		if (dataSocket != null) {
			try {
				dataSocket.close();
			} catch (IOException e) {
			}
		}
		dataSocket = null;
	}

	public boolean startUsingDataSocket() {
		try {
			dataSocket = dataSocketFactory.onTransfer();
			if (dataSocket == null) {
				return false;
			}
			dataOutputStream = dataSocket.getOutputStream();
			return true;
		} catch (IOException e) {
			dataSocket = null;
			return false;
		}
	}

	public InetAddress getDataSocketPasvIp() {
		return cmdSocket.getLocalAddress();
	}

	public void run() {
		sendInfo("220 MobileApFtp  ready\r\n");
		try {
			BufferedReader in = new BufferedReader(new InputStreamReader(
					cmdSocket.getInputStream()), 8192); // use 8k buffer
			while (true) {
				String line;
				line = in.readLine(); // will accept \r\n or \n for terminator
				if (line != null) {
					CmdManager.dispatchCommand(this, line);
				} else {
					break;
				}
			}
		} catch (IOException e) {
		}
		closeSocket();
	}

	public void closeSocket() {
		if (cmdSocket == null) {
			return;
		}
		try {
			cmdSocket.close();
		} catch (IOException e) {
		}
	}

	public int receiveFromDataSocket(byte[] buf) {
		int bytesRead;
		if (dataSocket == null) {
			return -2;
		}
		if (!dataSocket.isConnected()) {
			return -2;
		}
		InputStream in;
		try {
			in = dataSocket.getInputStream();
			while ((bytesRead = in.read(buf, 0, buf.length)) == 0) {
			}
			if (bytesRead == -1) {
				return -1;
			}
		} catch (IOException e) {
			return 0;
		}
		return bytesRead;
	}

	public boolean sendInfo(String sendInfo) {
		byte[] sendInfoBytes;
		try {
			sendInfoBytes = sendInfo.getBytes(encoding);
			BufferedOutputStream out = new BufferedOutputStream(
					cmdSocket.getOutputStream(), 10240);
			out.write(sendInfoBytes);
			out.flush();
			return true;
		} catch (IOException e) {
			closeSocket();
			return false;
		}

	}

	public boolean sendData(byte[] sendBytes, int start, int len) {
		if (dataOutputStream == null) {
			return false;
		}
		try {
			dataOutputStream.write(sendBytes, start, len);
		} catch (IOException e) {
			return false;
		}
		return true;
	}

	public boolean sendData(String sendInfo) {
		byte sendbyte[];
		if (dataOutputStream == null) {
			return false;
		}
		try {
			sendbyte = sendInfo.getBytes(encoding);
			dataOutputStream.write(sendbyte, 0, sendbyte.length);
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return true;
	}

	protected Socket getSocket() {
		return cmdSocket;
	}

	public boolean onPort(InetAddress dest, int port) {
		return dataSocketFactory.onPort(dest, port);
	}

	public SocketManager(Socket socket, DataSocket dataSocketFactory) {
		this.cmdSocket = socket;
		this.dataSocketFactory = dataSocketFactory;
	}

	public boolean isLogin() {
		return isLogin;
	}

	public File getWorkingDir() {
		return workingDir;
	}

	public int onPasv() {
		return dataSocketFactory.onPasv();
	}

	public void setWorkingDir(File workingDir) {
		try {
			this.workingDir = workingDir.getCanonicalFile().getAbsoluteFile();
		} catch (IOException e) {
		}
	}

	public Socket getDataSocket() {
		return dataSocket;
	}

	public File getRenameFrom() {
		return renameFrom;
	}

	public void setRenameFrom(File renameFrom) {
		this.renameFrom = renameFrom;
	}

	public void setDataSocket(Socket dataSocket) {
		this.dataSocket = dataSocket;
	}

	public void setEncoding(String encoding) {
		this.encoding = encoding;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getPwd() {
		return pwd;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

}
